import 'package:flutter_test/flutter_test.dart';

///类测试
///
main() {
  //simpleTest
  test("testSimple", () {
    Point(3, 3);
    Point.test();
    Point.test2(2, 2);
  });

  //父类
  test("testSuper", () {
    Employee.fromJson(Map());
  });

  //常量构造方法
  test("testConst", () {
    var a = const ImmutablePoint(1, 1); // 创建一个常量对象
    var b = ImmutablePoint(1, 1); // 创建一个非常量对象

    assert(!identical(a, b)); // 两者不是同一个实例!

    var c = const ImmutablePoint(1, 1);
    var d = const ImmutablePoint(1, 1);

    assert(identical(c, d)); // 它们是同一个实例。

    var e = const ImmutablePoint(1, 2);
    assert(!identical(e, d)); // 它们不是同一个实例。

    ImmutablePoint.fromJson({"x": 1, "y": 2});
  });

  //工厂构造方法
  test("testFactory", () {
    var logger = Logger('UI');
    var logger2 = Logger('UI');
    print("is Same ${identical(logger, logger2)}");

    logger.log('Button clicked');
  });

  test("testMixin", () {
    Test5().test();
  });

  test("testOperator", () {
    final v = Vector(2, 3);
    final w = Vector(2, 2);

    assert(v + w == Vector(4, 5));
    assert(v - w == Vector(0, 1));
  });

  test("testEnum", () {
    assert(Color.green.index == 1);
  });

  test("testNoSuchMethod", () {
    dynamic a = A();
    a.test();
  });

  test("testcovariant", () {
    Cat();
  });
}

///
///
///
/// 在没有声明构造函数的情况下， Dart 会提供一个默认的构造函数。 默认构造函数没有参数并会调用父类的无参构造函数
///
///
///
class Point {
  num x, y;

  //只能用一个构造方法
  Point(num x, num y) {
    // 还有更好的方式来实现下面代码，敬请关注。
    this.x = x;
    this.y = y;
  }

  //命名的构造方法，即使参数不一样，也不能同名
  Point.test2(int x, int y)
      : this.x = x,
        this.y = y {
    print("sdfa");
  }

  //构造函数可以用this简化
  //  Point(this.x, this.y);

  //命名构造函数
  Point.test() {
    x = 1;
    y = 2;
  }
}

///
///
///
/// 常量构造方法
///
///
///
class ImmutablePoint {
  final int x;
  final int y;

  //
  const ImmutablePoint(this.x, this.y);

  //命名构造函数
  ImmutablePoint.fromJson(Map<String, num> json)
      : x = json['x'],
        y = json['y'] {
    print('In Point.fromJson(): ($x, $y)');
  }
}

///
///
///
///工厂
///
///
///
class Logger {
  static void test() {
    return;
  }

  final String name;
  bool mute = false;

  static final Map<String, Logger> _cache = <String, Logger>{};

  //在构造函数前加factory表示是工厂
  factory Logger(String name) {
//    工厂构造函数无法访问 this
    // this.runtimeType;
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  factory Logger._internal2(String name) {
    return Logger(name);
  }

  //final 不能用在函数上
  void log(String msg) {
    if (!mute) print(msg);
  }
}

///
///
///
/// 构造函数测试
///
///
///
class Person {
  String firstName;

  Person.fromJson(Map data) {
    print('in Person');
  }
}

class Employee extends Person {
  // Person does not have a default constructor;
  // you must call super.fromJson(data).
  Employee.fromJson(Map data) : super.fromJson(data) {
    print('in Employee');
  }
}

///
///
///
///with implements extends 区别
///
///
///
class Television {
  void turnOn() {
    _illuminateDisplay();
  }

  void _illuminateDisplay() {
    print("_illuminateDisplay");
  }
}

class Update {
  void updateApp() {
    var test = 'abc';
    var str = 'name $test';
    print("updateApp ");
  }
}

class Charge {
  void chargeVip() {
    print("updateVip ");
  }
}

class RemoteControl {
  void turnOn() {
    print("RemoteControl turnOn");
  }
}

// 如果 Mixin 不希望作为常规类被使用，使用关键字 mixin 替换 class
mixin Test {
  void test() {
    print("test1");
  }
}

//使用 on 来指定可以使用 Mixin 的父类类型
mixin Test2 on Test {
  void test2() {
    print("test2");
  }
}

class Test3 with Test {
  void test3() {}
}

class Test4 with Test {
  void test4() {}
}

class Test5 extends Test3 {}

class SmartTelevision extends Television with Update, Charge {
  void turnOn() {
    super.turnOn();
    _bootNetworkInterface();
  }

  @override
  void chargeVip() {
    super.chargeVip();
    print("test");
  }

  void _bootNetworkInterface() {
    print("_bootNetworkInterface");
  }
}

class OldTelevision extends Television implements Charge {
  void turnOn() {
    super.turnOn();
  }

  //用implements必须要重写方法
  @override
  void chargeVip() {}
}

class NewTelevision extends Television {}

///
///
///
///抽象类及抽象方法
///
///
///
abstract class Doer {
  // 定义实例变量和方法 ...

  void doSomething(); // 定义一个抽象方法。

  void doSomething2() {
    print("doSomething2");
  }
}

class EffectiveDoer extends Doer {
  void doSomething() {
    print("doSomething");
  }

  @override
  void doSomething2() {
    super.doSomething2();
  }
}

///
///
///
///enum
///
///
///
enum Color { red, green, blue }

///
///
///
///operator
///
///
///
class Vector {
  final int x, y;

  Vector(this.x, this.y);

  Vector operator +(Vector v) => Vector(x + v.x, y + v.y);

  Vector operator -(Vector v) => Vector(x - v.x, y - v.y);

// 运算符 == 和 hashCode 部分没有列出。 有关详情，请参考下面的注释。
// ···
}

///
///
///
///noSuchMethod
///
///
///
class A {
  // 如果不重写 noSuchMethod，访问
  // 不存在的实例变量时会导致 NoSuchMethodError 错误。
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: ' +
        '${invocation.memberName}');
  }
}

///
///
///
///covariant
///
///
///
class Animal {
  void chase(Animal x) {
    print("chase");
  }
}

class Mouse extends Animal {}

class Cat extends Animal {
  //如果有合理的理由使用子类型，可以使用 covariant 关键字
  @override
//  void chase(Animal x) {  }
  void chase(covariant Mouse x) {}
}
